<?php

use Illuminate\Database\Capsule\Manager as DB;

#[订单售后]
class OrderaftersaleController extends AcommonController
{

    public function init()
    {
        $this->model      = new orderaftersaleModel();
        $this->table      = 'order_aftersale';
        $this->primaryKey = 'id';
        parent::init();
    }

    public function indexAction($returnData = FALSE)
    {
        if ($this->isPost()) {
            $query = orderaftersaleModel::query()->leftJoin('order', 'order.id', '=', 'order_aftersale.order_id')->with(['order', 'member']);
            $start_on    = $this->get('start_on');
            if (!empty($start_on)) {
                $query = $query->whereDate('order.created_at', '>=', $start_on);
            }
            $end_on = $this->get('end_on');
            if (!empty($end_on)) {
                $query = $query->whereDate('order.created_at', '<=', $start_on);
            }
            $apply_start_on    = $this->get('apply_start_on');
            if (!empty($apply_start_on)) {
                $query = $query->whereDate('order_aftersale.created_at', '>=', $apply_start_on);
            }
            $apply_end_on = $this->get('apply_end_on');
            if (!empty($apply_end_on)) {
                $query = $query->whereDate('order_aftersale.created_at', '<=', $apply_end_on);
            }
            $mode = $this->get('mode', 'all');
            if ($mode != 'all') {
                $query = $query->{$mode}();
            }
            $keywordsType = $this->get('keywordsType');
            $keywords     = $this->get('keywords');
            if ($keywords !== '') {
                switch ($keywordsType) {
                    case 'member_id':
                        $query = $query->where('order_aftersale.member_id', $keywords);
                        break;
                    case 'member_phone':
                        $query = $query->whereIn('order_aftersale.member_id', DB::table('member')->where('phone', 'like', "%{$keywords}%")->limit(20)->pluck('id'));
                        break;
                }
            }
            $order_sn     = $this->get('order_sn');
            if($order_sn) {
                $query = $query->whereIn('order_aftersale.order_id', orderModel::where('order_sn', 'like', "%{$order_sn}%")->pluck('id'));
            }
            if (!empty($this->search)) {
                $query = $query->where(function ($query) {
                    foreach ($this->search as $v) {
                        if (isset($v[3]) && strtolower($v[3]) == 'or') {
                            $query = $query->orWhere([$v]);
                        } else {
                            $query = $query->where([$v]);
                        }
                    }
                });
            }
            if (!empty($this->condition)) {
                $query = $query->where($this->condition);
            }
            if (!empty($this->condition_in)) {
                foreach ($this->condition_in as $k => $v) {
                    $query = $query->whereIn($v[0], $v[1]);
                }
            }
            $total = $query->count('order_aftersale.id');
            $query = $query->select(['order_aftersale.*', 'order.created_at as order_created_at']);
            $sort = $this->get('sort', 'sortorder');
            $order = $this->get('order', 'desc');
            $query = $query->orderBy('order_aftersale.'.$sort, $order)->orderBy('order_aftersale.'.$this->primaryKey, 'DESC');
            $page = $this->get('page');

            if (!empty($page)) {
                $limit = $this->get('rows', 10);
                $offset = ($page - 1) * $limit;
                $query = $query->offset($offset)->limit($limit);
            }
            $rows = $query->get();
            if(!empty($this->appends)){
                foreach ($this->appends as $append){
                    $rows = $rows->append($append);
                }
            }
            if(!empty($this->hiddens)){
                $rows = $rows->makeHidden($this->hiddens);
            }
            json(['total' => $total, 'rows' => $rows]);
        }else{
            $this->_view->display( strtolower($this->controller) . '/index.html');
        }
    }

    public function editAction()
    {
        if (!$this->isPost()) {
            $this->model = $this->model->with(['order', 'item', 'member', 'logs', 'return']);
        }
        parent::editAction();
    }

    #[退货单]
    public function returnAction()
    {
        if($this->isPost()) {
            $query = (new orderaftersalereturnModel)->with(['order', 'aftersale', 'member']);
            $total = $query->count();
            $sort = $this->get('sort', 'sortorder');
            $order = $this->get('order', 'desc');
            $query = $query->orderBy($sort, $order)->orderBy($this->primaryKey, 'DESC');
            $page = $this->get('page');

            if (!empty($page)) {
                $limit = $this->get('rows', 10);
                $offset = ($page - 1) * $limit;
                $query = $query->offset($offset)->limit($limit);
            }
            $rows = $query->get();
            json(['total' => $total, 'rows' => $rows]);
        }else{
            $this->_view->display( strtolower($this->controller) . '/return.html');
        }
    }

    #[同意退款]
    public function agreeAction()
    {
        $id           = $this->get('id');
        $refund_money = round($this->get('refund_money', 0), 2);
        if ($refund_money < 0) {
            ret(30001, '退款金额不能小于 0');
        }

        $aftersale = $this->model->where('id', $id)->first();
        if (!$aftersale) {
            ret(30002, '售后单不存在或不可退款');
        }

        $order = orderModel::with('item')->where('id', $aftersale->order_id)->first();
        if (!$order) {
            ret(30003, '订单不存在');
        }
        $items = $order->item;
        $items = array_column($items->toArray(), null, 'id');

        // 当前订单已退款总金额
        $refunded_money = array_sum(array_column($items, 'refund_fee'));
        // 剩余可退款金额
        $refund_surplus_money = $order->pay_fee - $refunded_money;
        // 如果退款金额大于订单支付总金额
        if ($refund_money > $refund_surplus_money) {
            ret(30004, '退款总金额不能大于实际支付金额');
        }
        $item = $items[$aftersale['order_item_id']];
        if (!$item || in_array($item['refund_status'], [
                orderitemModel::REFUND_STATUS_OK,
                orderitemModel::REFUND_STATUS_FINISH,
            ])) {
            ret(30005, '订单商品已退款，不能重复退款');
        }

        $orderItem = orderitemModel::find($item['id']);
        DB::transaction(function () use ($aftersale, $order, $orderItem, $refund_money, $refund_surplus_money) {

            $aftersale->aftersale_status = orderaftersaleModel::AFTERSALE_STATUS_OK;    // 售后同意
            $aftersale->refund_status    = orderaftersaleModel::REFUND_STATUS_FINISH;    // 售后同意退款
            $aftersale->refund_fee       = $refund_money;     // 退款金额
            $aftersale->save();

            // 增加售后单变动记录
            orderaftersalelogModel::operAdd($order, $aftersale, ['id' => $this->auth->user_id], 'admin', [
                'reason'  => '卖家同意退款',
                'content' => '售后订单已退款',
                'images'  => []
            ]);

            $orderItem->aftersale_status = orderitemModel::AFTERSALE_STATUS_OK;
            $orderItem->save();
            orderactionModel::operAdd($order, $orderItem, ['id' => $this->auth->user_id], 'admin', $aftersale->aftersale_sn . ' 管理员同意售后退款');

            // 退款 -- 在此加入订单退款后任务队列
            orderModel::startRefund($order, $orderItem, $refund_money, ['id' => $this->auth->user_id], $aftersale->aftersale_sn . ' 管理员同意售后退款');

            $data = ['aftersale' => $aftersale, 'order' => $order, 'item' => $orderItem];
            Hook::emit('aftersale_finish', $data);
        });

        ret(0, '操作成功');
    }

    #[同意申请]
    public function agreeApplyAction()
    {
        $id        = $this->get('id');
        $aftersale = $this->model->where('id', $id)->first();
        if (!$aftersale) {
            ret(30002, '售后单不存在');
        }

        $order = orderModel::with('item')->where('id', $aftersale->order_id)->first();
        if (!$order) {
            ret(30003, '订单不存在');
        }

        DB::transaction(function () use ($aftersale, $order) {
            $aftersale->aftersale_status = orderaftersaleModel::AFTERSALE_STATUS_AGREE;    // 售后同意
            $aftersale->save();

            // 增加售后单变动记录
            orderaftersalelogModel::operAdd($order, $aftersale, ['id' => $this->auth->user_id], 'admin', [
                'reason'  => '卖家同意售后申请',
                'content' => '售后单申请已通过',
                'images'  => []
            ]);

            // 增加退货单记录
            $row = [
                'member_id'          => $aftersale->member_id,
                'order_id'           => $order->id,
                'order_aftersale_id' => $aftersale->id,
                'created_at'         => date('Y-m-d H:i:s')
            ];
            orderaftersalereturnModel::insert($row);
        });

        ret(0, '操作成功');
    }

    #[拒绝申请]
    public function rejectAction()
    {
        $id         = $this->get('id');
        $refuse_msg = $this->get('refuse_msg');
        if (!$refuse_msg) {
            ret(30001, '请输入拒绝原因');
        }

        $aftersale = $this->model->find($id);
        if (!$aftersale) {
            ret(30002, '售后单不存在或不可拒绝');
        }

        $order     = orderModel::find($aftersale->order_id);
        $orderItem = orderitemModel::find($aftersale->order_item_id);
        if (!$order || !$orderItem) {
            ret(30003, '订单或订单商品不存在');
        }

        DB::transaction(function () use ($aftersale, $order, $orderItem, $refuse_msg) {

            $aftersale->aftersale_status = orderaftersaleModel::AFTERSALE_STATUS_REFUSE;    // 售后拒绝
            $aftersale->save();
            // 增加售后单变动记录
            orderaftersalelogModel::operAdd($order, $aftersale, ['id' => $this->auth->user_id], 'admin', [
                'reason'  => '卖家拒绝售后',
                'content' => $refuse_msg,
                'images'  => []
            ]);

            $orderItem->aftersale_status = orderitemModel::AFTERSALE_STATUS_REFUSE;    // 拒绝售后
            $orderItem->save();

            orderactionModel::operAdd($order, $orderItem, ['id' => $this->auth->user_id], 'admin', '管理员拒绝订单售后：' . $refuse_msg);

            // 售后单拒绝后
            $data = ['aftersale' => $aftersale, 'order' => $order, 'item' => $orderItem];
            Hook::emit('aftersale_refuse', $data);
        });

        ret(0, '操作成功');
    }

    #[售后完成]
    public function finishAction()
    {
        $id        = $this->get('id');
        $aftersale = $this->model->where('id', $id)->first();
        if (!$aftersale) {
            ret(30001, '售后单不存在或不可完成');
        }

        $order     = orderModel::find($aftersale->order_id);
        $orderItem = orderitemModel::find($aftersale->order_item_id);
        if (!$order || !$orderItem) {
            ret(30002, '订单或订单商品不存在');
        }

        DB::transaction(function () use ($aftersale, $order, $orderItem) {

            $aftersale->aftersale_status = orderaftersaleModel::AFTERSALE_STATUS_OK;    // 售后完成
            $aftersale->save();
            // 增加售后单变动记录、
            orderaftersalelogModel::operAdd($order, $aftersale, ['id' => $this->auth->user_id], 'admin', [
                'reason'  => '卖家完成售后',
                'content' => '售后订单已完成',
                'images'  => []
            ]);

            $orderItem->aftersale_status = orderitemModel::AFTERSALE_STATUS_OK;
            $orderItem->save();
            orderactionModel::operAdd($order, $orderItem, ['id' => $this->auth->user_id], 'admin', '管理员完成售后');

            // 售后单完成之后
            $data = ['aftersale' => $aftersale, 'order' => $order, 'item' => $orderItem];
            Hook::emit('aftersale_finish', $data);
        });

        ret(0, '操作成功');
    }

    #[售后回复]
    public function replyAction()
    {
        if (!$this->isPost()) {
            $this->_view->assign('id', $this->get('id'));
            $this->_view->display(strtolower($this->controller) . '/reply.html');
        } else {
            $id      = $this->get('id');
            $reason  = $this->get('reason', '卖家留言');
            $content = $this->get('content', '');
            $images  = $this->get('images', []);

            if (!$content) {
                ret(30001, '留言内容不能为空');
            }

            $aftersale = $this->model->find($id);
            if (!$aftersale) {
                ret(30002, '售后单不存在');
            }

            $order = orderModel::with('item')->where('id', $aftersale->order_id)->first();
            if (!$order) {
                ret(30003, '订单不存在');
            }

            $aftersalelog = DB::transaction(function () use ($order, $aftersale, $reason, $content, $images) {
                if ($aftersale['aftersale_status'] == 0) {
                    $aftersale->aftersale_status = orderaftersaleModel::AFTERSALE_STATUS_AFTERING;    // 售后处理中
                    $aftersale->save();
                }

                // 增加售后单变动记录
                return orderaftersalelogModel::operAdd($order, $aftersale, ['id' => $this->auth->user_id], 'admin', [
                    'reason'  => $reason,
                    'content' => $content,
                    'images'  => $images
                ]);
            });

            ret(0, '操作成功', $aftersalelog);
        }
    }

    #[售后导出]
    public function exportAction()
    {
        $type     = $this->get('keywordsType');
        $keywords = $this->get('keywords');
        $startOn  = $this->get('start_on');
        $endOn    = $this->get('end_on');
        $mode     = $this->get('mode');
        $orderSn = $this->get('order_sn');
        $applyStartOn = $this->get('apply_start_on');
        $applyEndOn = $this->get('apply_end_on');
        $dirpath = APP_PATH . '/public/excel/';
        if ($dirpath !== '.' && !file_exists($dirpath)) {
            mkdir($dirpath, 0777, true);
        }
        $filename = 'orderaftersale' . date('Ymd') . uniqid() . '.xlsx';
        $filepath = $dirpath . $filename;
        $res      = exec("php " . APP_PATH . "/public/cli.php export/orderaftersale \"type={$type}&keywords={$keywords}&startOn={$startOn}&endOn={$endOn}&applyStartOn={$applyStartOn}&applyEndOn={$applyEndOn}&mode={$mode}&orderSn={$orderSn}&path={$filepath}\"");
        if ($res === 'Done' && file_exists($dirpath . $filename)) {
			if( $webpath = syncFile($filepath) ){
                ret(0, '订单导出excel成功', $webpath);
            }
        }
        ret(30003, '订单导出失败');
    }


}
